package com.my.controller;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializer;
import com.my.pojo.Business;
import com.my.pojo.User;
import com.my.service.IUserService;
import com.my.util.JWTUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RestController
@CrossOrigin("*")
@RequestMapping("/user")
public class UserController {

    IUserService iUserService;

    @Autowired
    public void setIBusinessService(IUserService iUserService) {
        this.iUserService = iUserService;
    }

    RedisTemplate<String, String> redisTemplate;

    @Autowired
    public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    //商户对象json格式器
    private Gson getClassJSON() {
        return new GsonBuilder().registerTypeAdapter(User.class,
                (JsonSerializer<User>) (src, typeOfSrc, context) -> {
                    JsonObject jsonObject = new JsonObject();
                    jsonObject.addProperty("username", src.getUsername());
                    jsonObject.addProperty("phone", src.getPhone());
                    jsonObject.addProperty("email", src.getEmail());
                    return jsonObject;
                }).create();
    }

    private boolean isEmail(String email) {
        String str = "^([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)*@([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[\\.][A-Za-z]{2,3}([\\.][A-Za-z]{2})?$";
        Pattern p = Pattern.compile(str);
        Matcher m = p.matcher(email);
        return m.matches();
    }

    private boolean isPhone(String phone) {
        Pattern pattern = Pattern.compile("^[1]\\d{10}$");
        return pattern.matcher(phone).matches();
    }

    private void putMessage(Map<String, String> map, String code, String message) {
        map.put("code", code);
        map.put("message", message);
    }

    /**
     * 账号密码登录
     *
     * @param username 登录用户名，可能为用户名、邮箱、电话
     * @param password 登录密码
     * @return 状态码+信息+用户对象(登陆成功时)
     * 状态码：
     * login_500   不存在用户名/密码错误
     * login_501    用户名/密码为空
     * login_200    登录成功
     */
    @RequestMapping("/loginByPassword")
    public String loginByPassword(String username, String password) {
        Map<String, String> map = new HashMap<>();
        System.out.println(username + ":" + password);
        if (username == null || password == null) {
            this.putMessage(map, "login_501", "empty data");
        } else {
            String columnName = isEmail(username) ? "email" : isPhone(username) ? "phone" : "username";
            User user = iUserService.loginByPassword(username, password, columnName);
            if (user != null) {
                this.putMessage(map, "200", "success");
                String toke = JWTUtils.geneJsonWebToken(user);
                map.put("token", toke);
                redisTemplate.opsForValue().set(toke, user.getUserId().toString(), 1, TimeUnit.DAYS);
                map.put("user", this.getClassJSON().toJson(user));
            } else {
                this.putMessage(map, "login_500", "user not find");
            }
        }
        return new Gson().toJson(map);
    }

    /**
     * 人脸识别登录
     *
     * @param MD5 人脸图像MD5
     * @return 状态码+信息+用户对象(识别成功时)
     * 状态码：
     * 500   识别失败
     * 200    识别成功
     */
    @RequestMapping("/loginByFace")
    public String loginByFace(String MD5) {
        Map<String, String> map = new HashMap<>();
        if (MD5.startsWith("data:image/png;base64,")) {
            MD5 = MD5.substring("data:image/png;base64,".length());
        }
        User user = this.iUserService.loginByFace(MD5);
        if (user != null) {
            this.putMessage(map, "200", "success");
            String toke = JWTUtils.geneJsonWebToken(user);
            map.put("token", toke);
            redisTemplate.opsForValue().set(toke, user.getUserId().toString(), 1, TimeUnit.DAYS);
            map.put("user", this.getClassJSON().toJson(user));
        } else {
            map.put("code", "500");
            this.putMessage(map, "login_500", "user not find");
        }
        return new Gson().toJson(map);
    }

    /**
     * 手机短信验证登录
     *
     * @param phone 手机号
     * @param code  验证码
     * @return 状态码+信息+用户对象(登录成功时)
     * 状态码:
     * login_500 未找到用户
     * 200 登录成功
     */
    @RequestMapping("/loginByPhone")
    public String loginByPhone(String phone, String code) {
        Map<String, String> map = new HashMap<>();
        User user = this.iUserService.loginByPhone(phone, code);
        if (user == null) {
            this.putMessage(map, "login_500", "user not find");
        } else {
            this.putMessage(map, "200", "success");
            String toke = JWTUtils.geneJsonWebToken(user);
            map.put("token", toke);
            redisTemplate.opsForValue().set(toke, user.getUserId().toString(), 1, TimeUnit.DAYS);
            map.put("user", this.getClassJSON().toJson(user));
        }
        return new Gson().toJson(map);
    }

    /**
     * 邮箱短信验证登录
     *
     * @param email 手机号
     * @param code  验证码
     * @return 状态码+信息+用户对象(登录成功时)
     * 状态码:
     */
    @RequestMapping("/loginByEmail")
    public String loginByEmail(String email, String code) {
        Map<String, String> map = new HashMap<>();
        User user = this.iUserService.loginByEmail(email, code);
        if (user == null) {
            this.putMessage(map, "login_500", "user not find");
        } else {
            this.putMessage(map, "200", "success");
            String toke = JWTUtils.geneJsonWebToken(user);
            map.put("token", toke);
            System.out.println(toke);
            redisTemplate.opsForValue().set(toke, user.getUserId().toString(), 1, TimeUnit.DAYS);
            map.put("user", this.getClassJSON().toJson(user));
        }
        return new Gson().toJson(map);
    }

    /**
     * 发送手机验证码
     *
     * @param phone 手机号
     * @return 状态码+信息
     * 状态码:
     * login_501   参数非手机号
     * login_502   手机号未注册
     * 200          登陆成功
     */
    @RequestMapping("/sendPhoneMessage")
    public String sendPhoneMessage(String phone) {
        Map<String, String> map = new HashMap<>();
        Gson gson = new Gson();
        if (!isPhone(phone)) {
            this.putMessage(map, "login_501", "wrong type");
        } else {
            Integer res = this.iUserService.sendPhoneMessage(phone);
            if (res == -1) {
                this.putMessage(map, "login_502", "not found");
            } else {
                this.putMessage(map, "200", "success");
            }
        }
        return gson.toJson(map);
    }

    /**
     * 发送邮箱验证码
     *
     * @param email 邮箱号
     * @return 状态码+信息
     * 状态码:
     * login_501   参数非邮箱
     * login_502   邮箱未注册
     * 200          登陆成功
     */
    @RequestMapping("/sendEmailMessage")
    public String sendEmailMessage(String email) {
        Map<String, String> map = new HashMap<>();
        Gson gson = new Gson();
        if (!isEmail(email)) {
            this.putMessage(map, "login_501", "wrong type");
        } else {
            Integer res = this.iUserService.sendEmailMessage(email);
            if (res == -1) {
                this.putMessage(map, "login_502", "not found");
            } else {
                this.putMessage(map, "200", "success");
            }
        }
        return gson.toJson(map);
    }

    /**
     * 商户注册
     *
     * @param username 用户名
     * @param password 密码
     * @param face     脸部数据
     * @param phone    手机号
     * @param email    邮箱
     * @return 状态码+信息
     * 状态码:
     * register_501    用户名/密码为空
     * register_502    手机/邮箱格式错误
     * register_503    用户名/邮箱/手机/商铺名重复
     * register_504    人脸识别错误
     * register_505    sql执行时报错
     * 200             注册成功
     */
    @RequestMapping("/register")
    public String register(String username, String password, String face, String phone, String email) {
        Map<String, String> map = new HashMap<>();
        Gson gson = new Gson();
        if (face.startsWith("data:image/png;base64,")) {
            face = face.substring("data:image/png;base64,".length());

            if (username == null || username.trim().equals("")) {
                this.putMessage(map, "register_501", "empty data");
            } else if (password == null || password.trim().equals("")) {
                this.putMessage(map, "register_501", "empty data");
            } else if (!isPhone(phone) || !isEmail(email)) {
                this.putMessage(map, "register_502", "wrong type");
            } else {
                User user = new User();
                user.setUsername(username);
                user.setPassword(password);
                user.setFace(face);
                user.setPhone(phone);
                user.setEmail(email);
                user.setStatus(0);
                Integer res = this.iUserService.register(user);
                if (res == -1) {
                    this.putMessage(map, "register_503", "repeated data");
                } else if (res == -2) {
                    this.putMessage(map, "register_504", "face error");
                } else if (res == 0) {
                    this.putMessage(map, "register_505", "sql error");
                } else if (res > 0) {
                    this.putMessage(map, "200", "success");
                }
            }
        } else {
            this.putMessage(map, "register_506", "error img");
        }
        return gson.toJson(map);
    }


    @RequestMapping("/author")
    public String getAuthor(HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();
        String token = req.getHeader("token");
        Integer userId = JWTUtils.getId(token);
        if(userId == null) {
            putMessage(map, "500", "token解析失败");
        } else {
            User user = iUserService.findById(userId);
            if(user != null) {
                putMessage(map, "200", "校验成功");
                map.put("user", getClassJSON().toJson(user));
            } else {
                putMessage(map, "502", "未找到用户");
            }
        }

        return new Gson().toJson(map);
    }

    @RequestMapping("/changePassword")
    public String changePassword(String password, HttpServletRequest req) {
        Map<String, String> map = new HashMap<>();
        if(password.trim().equals("")) {
            putMessage(map, "505", "密码为空");
        } else {
            String token = req.getHeader("token");
            Integer userId = JWTUtils.getId(token);

            if(userId == null) {
                putMessage(map, "500", "token解析失败");
            } else {
                Integer res = iUserService.changePassword(userId, password);
                if(res == -1) {
                    putMessage(map, "502", "未找到用户");
                } else if(res == -2){
                    putMessage(map, "503", "sql错误");
                }
            }
        }
        return new Gson().toJson(map);
    }


}
